<template>
  <ConfigProvider
    :theme="{
      components: {
        Tabs: {
          lineWidth: 0,
        },
        Input: borderStyle,
        Select: borderStyle,
        InputNumber: borderStyle,
      },
    }"
  >
    <Form
      ref="tabFormRef"
      name="tab"
      :model="pageData"
      class="pro-form-modal"
      :disabled="readonly"
    >
      <Row :gutter="40"
        ><Col :span="6">
          <FormItem
            label="协议版本号"
            name="protobufVersion"
            :rules="[
              {
                required: true,
                type: 'array',
                message: '请选择协议版本号',
                trigger: 'blur',
              },
            ]"
          >
            <Select
              v-model:value="pageData.protobufVersion"
              placeholder="请选择协议版本号"
              mode="multiple"
              :showArrow="true"
              :allowClear="false"
              :options="protobufVersionOption"
            />
          </FormItem>
        </Col>
        <Col :span="10">
          <FormItem
            label="配置类型/型号"
            name="modelIds"
            :rules="[
              {
                required: true,
                type: 'array',
                message: '请选择配置类型型号',
                trigger: 'blur',
              },
            ]"
          >
            <TreeSelect
              v-model:value="pageData.modelIds"
              :fieldNames="{
                children: 'childs',
                label: 'model',
                value: 'modelId',
              }"
              placeholder="请选择"
              :showCheckedStrategy="TreeSelect.SHOW_ALL"
              :treeData="modelTreeData"
              treeCheckable
              :maxTagCount="1"
              :allowClear="true"
            >
            </TreeSelect>
          </FormItem>
        </Col>
        <Col :span="8">
          <FormItem
            label="配置说明"
            name="configExplain"
            :rules="[
              { required: true, message: '请输入配置说明', trigger: 'blur' },
            ]"
          >
            <Input
              v-model:value="pageData.configExplain"
              placeholder="请输入配置说明"
              :allowClear="false"
            />
          </FormItem>
        </Col>
      </Row>
    </Form>
    <Tabs v-model:activeKey="activeKey" tab-position="left">
      <template #renderTabBar>
        <Collapse
          v-model:activeKey="collapseKey"
          ghost
          accordion
          class="tab-collapse"
          ><template v-for="(item, index) in panes">
            <CollapsePanel
              v-if="item.group.length"
              :header="item.title"
              :key="index"
            >
              <Space direction="vertical">
                <Button
                  v-for="button in item.group"
                  :key="`button${button.key}`"
                  type="text"
                  block
                  :class="{ active: activeKey == button.key }"
                  @click="activeKey = button.key"
                  ><Space
                    ><Checkbox
                      v-if="!readonly"
                      v-model:checked="button.check"
                      :key="`checked${button.key}`"
                    />{{ button.title }}</Space
                  ></Button
                >
              </Space>
            </CollapsePanel>
          </template>
        </Collapse>
      </template>
      <template v-for="paneGroup in panes">
        <TabPane
          v-for="pane in paneGroup.group"
          :key="pane.key"
          :tab="pane.title"
          :force-render="!readonly && pane.check"
        >
          <component
            :is="pane.content"
            :pageData="pageData"
            :ref="(el:any) => setComponentRef(el, pane.key)"
            :readonly="readonly"
            :key="readonly"
          />
        </TabPane>
      </template>
    </Tabs>
    <Space
      class="footer-buttons"
      v-if="pageData.approvalStatus !== '1'"
      v-hasPermission="'quickConfig:edit'"
    >
      <Button v-if="!readonly" type="primary" :loading="loading" @click="save"
        >保存</Button
      >
      <Button v-else type="primary" :loading="loading" @click="editor"
        >编辑</Button
      >
      <Button v-if="!readonly" @click="cancel">取消</Button>
    </Space>
  </ConfigProvider>
</template>

<script setup lang="tsx">
import { computed, provide, reactive, ref, shallowRef } from 'vue';
import Brand from '@/views/components/Brand.vue';
import Device from '@/views/components/Device.vue';
import Energy from '@/views/components/Energy.vue';
import File from '@/views/components/File.vue';
import GpioControl from '@/views/components/GpioControl.vue';
import Gps from '@/views/components/Gps.vue';
import Mesh from '@/views/components/Mesh.vue';
import Meter from '@/views/components/Meter.vue';
import Mqtt_2 from '@/views/components/Mqtt-2.vue';
import Mqtt from '@/views/components/Mqtt.vue';
import Netty from '@/views/components/Netty.vue';
import Ntp from '@/views/components/Ntp.vue';
import Report from '@/views/components/Report.vue';
import RunningMode from '@/views/components/RunningMode.vue';
import Theme from '@/views/components/Theme.vue';
import Volume from '@/views/components/Volume.vue';
import Warn from '@/views/components/Warn.vue';
import Weather from '@/views/components/Weather.vue';
import {
  Button,
  Checkbox,
  Col,
  Collapse,
  CollapsePanel,
  ConfigProvider,
  Form,
  FormItem,
  Input,
  Row,
  Select,
  Space,
  TabPane,
  Tabs,
  TreeSelect,
  message,
} from 'ant-design-vue';
import { omit } from 'lodash-es';
import { protobufVersionOption } from '@/constant/push';
import { borderStyle } from '@/constant/theme';
import { addQuickConfig, deviceModelPull, updateQuickConfig } from '@/api/push';

defineOptions({
  name: 'ConfigTabs',
});

interface Props {
  pageData: any;
  type: string;
}

const props = defineProps<Props>();
console.log(props.pageData, 'props.pageData.protobufVersion');

const modelTreeData = ref([]);
deviceModelPull().then((res: any) => {
  modelTreeData.value = res.data;
});

const componentRefs: any = {};
const setComponentRef = (el: any, key: any) => {
  if (el) {
    componentRefs[key] = el;
  }
};

const findTypesByModelIds = (modelIds: any) => {
  const typesSet = new Set();
  modelTreeData.value.forEach((group: any) => {
    group.childs.forEach((child: any) => {
      if (modelIds.includes(child.modelId)) {
        typesSet.add(child.type);
      }
    });
  });
  return Array.from(typesSet);
};
console.log(props.pageData.protobufVersion, '1');

props.pageData.protobufVersion = Array.isArray(props.pageData.protobufVersion)
  ? props.pageData.protobufVersion
  : props.pageData.protobufVersion?.split(',') || [];
props.pageData.modelIds = props.pageData.modelIds || [];
const loading = ref(false);
const configType = props.pageData.configType;
const readonly = ref(props.type == 'info');
const p = reactive([
  {
    title: '预警管理',
    group: [
      {
        title: '运行模式',
        key: 'runningMode',
        check: configType.includes('运行模式'),
        content: shallowRef(RunningMode),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'runningModeConfigsJson',
      },
      {
        title: '授权参数',
        key: 'mqtt',
        check: configType.includes('授权参数'),
        content: shallowRef(Mqtt),
        v: ['1'],
        t: ['1', '2', '3'],
        params: 'mqttConfigsJson',
      },
      {
        title: '授权参数',
        key: 'mqtt',
        check: configType.includes('授权参数'),
        content: shallowRef(Mqtt),
        v: ['2'],
        t: ['3'],
        params: 'mqttConfigsJson',
      },
      {
        title: '授权参数',
        key: 'mqtt_2',
        check: configType.includes('授权参数'),
        content: shallowRef(Mqtt_2),
        v: ['2'],
        t: ['1', '2'],
        params: 'mqttConfigsJson',
      },
      {
        title: '预警参数',
        key: 'warn',
        check: configType.includes('预警参数'),
        content: shallowRef(Warn),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'warnConfigsJson',
      },
      {
        title: '速报参数',
        key: 'report',
        check: configType.includes('速报参数'),
        content: shallowRef(Report),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'reportConfigsJson',
      },
      {
        title: '声音参数',
        key: 'volume',
        check: configType.includes('声音参数'),
        content: shallowRef(Volume),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'volumeConfigsJson',
      },
    ],
  },
  {
    title: '服务管理',
    group: [
      {
        title: '管理服务',
        key: 'netty',
        check: configType.includes('管理服务'),
        content: shallowRef(Netty),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'nettyConfigsJson',
      },
      {
        title: '文件服务',
        key: 'file',
        check: configType.includes('文件服务'),
        content: shallowRef(File),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'fileConfigsJson',
      },
      {
        title: '定位服务',
        key: 'gps',
        check: configType.includes('定位服务'),
        content: shallowRef(Gps),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'gpsConfigsJson',
      },
      {
        title: '对时服务',
        key: 'ntp',
        check: configType.includes('对时服务'),
        content: shallowRef(Ntp),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'ntpConfigsJson',
      },
      {
        title: '气象服务',
        key: 'weather',
        check: configType.includes('气象服务'),
        content: shallowRef(Weather),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'weatherConfigsJson',
      },
    ],
  },
  {
    title: '设备管理',
    group: [
      {
        title: '首页配置',
        key: 'theme',
        check: configType.includes('首页配置'),
        content: shallowRef(Theme),
        v: ['1', '2'],
        t: ['1', '2'],
        params: 'themeConfigsJson',
      },
      {
        title: '屏显配置',
        key: 'energy',
        check: configType.includes('屏显配置'),
        content: shallowRef(Energy),
        v: ['1', '2'],
        t: ['1', '2'],
        params: 'energyConfigsJson',
      },

      {
        title: '设备配置',
        key: 'device',
        check: configType.includes('设备配置'),
        content: shallowRef(Device),
        v: ['1', '2'],
        t: ['1', '2', '3'],
        params: 'deviceConfigsJson',
      },
      {
        title: '品牌配置',
        key: 'brand',
        check: configType.includes('品牌配置'),
        content: shallowRef(Brand),
        v: ['2'],
        t: ['3'],
        params: 'brandConfigsJson',
      },
    ],
  },
  {
    title: '外围配置',
    group: [
      {
        title: '无线组网',
        key: 'mesh',
        check: configType.includes('无线组网'),
        content: shallowRef(Mesh),
        v: ['1', '2'],
        t: ['1', '2'],
        params: 'meshConfigsJson',
      },
      {
        title: 'GPIO配置',
        key: 'gpioControl',
        check: configType.includes('GPIO配置'),
        content: shallowRef(GpioControl),
        v: ['1', '2'],
        t: ['1'],
        params: 'gpioControlConfigsJson',
      },
      {
        title: '烈度计',
        key: 'meter',
        check: configType.includes('烈度计'),
        content: shallowRef(Meter),
        v: ['1', '2'],
        t: ['1', '2'],
        params: 'intensityMeterConfigMessagesJson',
      },
    ],
  },
]);
const panes: any = computed(() => {
  return p.map((item) => {
    const group = item.group.filter(
      (Item: any) =>
        props.pageData.protobufVersion.length > 0 &&
        props.pageData.modelIds.length > 0 &&
        props.pageData.protobufVersion.every((v: any) => Item.v.includes(v)) &&
        findTypesByModelIds(props.pageData.modelIds).every((t: any) =>
          Item.t.includes(t),
        ) &&
        (!readonly.value || configType.includes(Item.title)),
    );
    return { title: item.title, group };
  });
});
const collapseKey = ref(0);
const activeKey = ref(panes.value[0].group[0]?.key);
const findIndex = (array: any, fun: any) => {
  for (let i = 0; i < array.length; i++) {
    const subArray = array[i].group;
    const item = subArray.find(fun);
    if (item) {
      return { outerIndex: i, item };
    }
  }
  return { outerIndex: -1, item: null };
};
const fistCheck = findIndex(panes.value, (item: any) => item.check);
if (fistCheck.item) {
  collapseKey.value = fistCheck.outerIndex;
  activeKey.value = fistCheck.item.key;
}
const tabFormRef = shallowRef();
provide('fastConfig', null);
provide('tab', null);
const emit = defineEmits(['close']);

const filtCheckTab = (array: any) => {
  let arr: any = [];
  for (let i = 0; i < array.length; i++) {
    const subArray = array[i].group;
    const checkArr = subArray.filter((item: any) => item.check);
    arr = arr.concat(checkArr);
  }
  return arr;
};

const filtAllCheckGroupToJSON = (array: any) => {
  let arr: any = [];
  for (let i = 0; i < array.length; i++) {
    const children = [];
    const subArray = array[i].group;
    for (let j = 0; j < subArray.length; j++) {
      const _pane = subArray[j];
      _pane.check && children.push({ title: _pane.title });
    }
    children.length && arr.push({ title: array[i].title, children });
  }
  return JSON.stringify(arr);
};

const collectParamsWithFalseCheck = (tree: any) => {
  let result: any = [];

  const traverse = (node: any) => {
    if (node.check === false && node.params) {
      result.push(node.params);
    }
    if (node.group && Array.isArray(node.group)) {
      node.group.forEach((child: any) => traverse(child));
    }
  };

  tree.forEach((node: any) => traverse(node));
  return result;
};
const editor = () => {
  readonly.value = false;
};
const cancel = () => {
  readonly.value = true;
  // emit('close', false);
};
const save = () => {
  console.log(panes.value, 'panes.value');
  tabFormRef.value.validateFields().then(
    async () => {
      const validateTab = filtCheckTab(panes.value);
      if (validateTab.length < 1) {
        message.warning('至少勾选一个配置');
        return;
      }
      const resTab = await Promise.all(
        validateTab.map(async (item: any) => {
          try {
            await componentRefs[item.key].save();
            return true;
          } catch (error) {
            return item.key;
          }
        }),
      );
      const firstReject = resTab.find((value) => value != true);
      if (firstReject) {
        const findReject = findIndex(
          panes.value,
          (item: any) => item.key == firstReject,
        );
        activeKey.value = firstReject;
        collapseKey.value = findReject.outerIndex;
      } else {
        const protobufVersion = props.pageData.protobufVersion.join();
        const configType = filtAllCheckGroupToJSON(panes.value);
        for (const key in props.pageData) {
          if (props.pageData[key] === '{}') {
            props.pageData[key] = null;
          }
        }
        const paramsList = collectParamsWithFalseCheck(panes.value);
        console.log(paramsList, 'paramsList');

        const queryParams = omit(props.pageData, paramsList);
        console.log(queryParams, 'queryParams');

        if (props.type == 'info') {
          await updateQuickConfig({
            ...props.pageData,
            protobufVersion,
            configType,
            modelAlwaysVOS: undefined,
          });
        } else {
          await addQuickConfig({
            ...props.pageData,
            protobufVersion,
            configType,
            modelAlwaysVOS: undefined,
          });
        }
        message.success('操作成功');
        emit('close', true);
      }
    },
    () => {},
  );
};
</script>
<style lang="scss" scoped>
.ant-tabs {
  height: 58vh;
}

:deep(h5) {
  width: 100%;
  font-size: 16px;
  margin: 0px 20px 20px 20px;
  padding-bottom: 5px;
  border-bottom: 1px outset;
}

:deep(.tips) {
  width: 100%;
  margin: 20px;
  &::before {
    display: inline-block;
    margin-inline-end: 4px;
    color: #ff4d4f;
    content: '*';
  }
}
.pro-form-modal {
  margin-left: 169px;
}
:deep(.pro-form-modal) {
  max-height: 99%;
  overflow-y: auto;
  margin-right: -24px;
  padding-right: 24px;
}
.footer-buttons {
  float: right;
  margin-bottom: -30px;
}
:deep(.footer-buttons) {
  display: none;
  position: absolute;
  bottom: -35px;
  right: 0;
}
:deep(.warn-form-modal) {
  .warn-none .ant-checkbox-group > {
    :nth-child(2),
    :nth-child(4),
    :nth-child(5),
    :nth-child(6),
    :nth-child(7) {
      display: none;
    }
  }
}
</style>
